package com.zqf.shiro.controller;

import com.alibaba.fastjson.JSONObject;
import com.zqf.shiro.filter.JwtToken;
import com.zqf.shiro.jwt.JwtAudience;
import com.zqf.shiro.pojo.LoginUser;
import com.zqf.shiro.pojo.Result;
import com.zqf.shiro.pojo.User;
import com.zqf.shiro.pojo.dto.UserDTO;
import com.zqf.shiro.service.UserService;
import com.zqf.shiro.utils.JwtHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.security.auth.message.AuthException;
import java.io.Serializable;
import java.util.Set;

/**
 * @author zqf
 */
@RestController
@RequestMapping("user/")
@Api(tags = "用户授权")
public class AuthController {

    @Autowired
    private UserService userService;

    @Resource
    private JwtAudience jwtAudience;

    @Resource
    private RedisTemplate<String, Serializable> redisTemplate;


    @PostMapping("jwtLogin")
    @ApiOperation("jwt令牌登录")
    public Result<JwtToken> jwtLogin(@RequestBody User userDto) {

        //根据用户名查询用户
        User user = userService.getUserByUserName(userDto.getUsername());
        if (user == null){
            return Result.error(500,"用户不存在");
        }
        //比对密码
        String password = new Md5Hash(userDto.getPassword(), user.getSalt(), 1024).toHex();
        if (!user.getPassword().equals(password)){
            return Result.error(500,"密码错误");
        }
        //查询用户角色信息
        Set<String>roles = userService.queryUserRoles(user.getId());
        String jti = JwtHelper.createJti();
        LoginUser loginUser = new LoginUser();
        loginUser.setId(user.getId());
        loginUser.setUsername(user.getUsername());
        loginUser.setJti(jti);
        loginUser.setRoles(roles);

        // 生成新的token
        String accessToken = JwtHelper.createAccessToken(loginUser, jwtAudience.getIss(), jwtAudience.getAud(),
                jwtAudience.getExpirationSeconds() * 1000L, jwtAudience.getBase64Secret());


        //刷新token
        String refreshToken = JwtHelper.createRefreshToken(loginUser.getUsername(), jwtAudience.getIss(), jwtAudience.getAud(),
                jwtAudience.getExpirationSeconds() * 70000L, jwtAudience.getBase64Secret());

        //缓存至redis
        redisTemplate.opsForSet().add("shiro:user" + loginUser.getUsername(), jti);

        JwtToken token = new JwtToken(accessToken, refreshToken, "Bearer", jwtAudience.getExpirationSeconds());
        return Result.<JwtToken>build()
                .ok()
                .withData(token);
    }


    @PostMapping("/registry")
    @ApiOperation("注册")
    public Boolean registry(@RequestBody UserDTO user) throws AuthException {
        return userService.addUser(user);
    }

}
